//
// Copyright (C) [2024] Xingyun Integrated Circuit, Inc.
//
// GreenCode was a private technology asset of Xingyun Integrated Circuit， Inc （Confidential）
//  Author: Shawn.Tan
//  Date : 2025.10.28
//
//  History : Initial Version 2025.10.28
//
//
#ifndef Green_Log_H
#define Green_Log_H

#include <cassert>
#include <ostream>

namespace Green {

  /*
    LL Loging level
   */
  enum class LL : unsigned char {
    trace  = 0,
    debug  = 1,
    info   = 2,
    warn   = 3,
    error  = 4,
    fail   = 5,
    notice = 6
  };

  class Logger {
  public:
    ~Logger() { } //!< Destructor.
    inline bool Log(LL logLevel) const { return (logLevel >= mLogLevel); } //!< Return whether logging is enable at the specified log-leve
    void DumpFail(const char* msg, const char* fileName, int lineNo, const char* funcName);
    void SetLevel(const char* logLevel);
    std::ostream& Stream(LL logLvel);
    std::ostream& TestStream() { return mTestStream; }

    static void Initialize();
    static void Destroy();
  private:
    Logger(std::ostream& stream, std::ostream& errorStream, std::ostream& testStream);
    void Fail(const char* msg, const char* fileName, int lineNo, const char* funcName);
  private:
    std::ostream& mOStream;
    std::ostream& mErrorStream;
    std::ostream& mTestStream;
    LL mLogLevel;
  };

  extern Logger* gLog;
  extern char* gSmallBuffer;

#define LOG(LEVEL) if (gLog->Log(LL::LEVEL)) gLog->Stream(LL::LEVEL)
#define FAIL(msg) gLog->DumpFail(msg, __FILE__,__LINE__,__func__)
#define SET_LOG_LEVEL(level) gLog->SetLevel(level)
#define TEST_INFO gLog->TestStream() << "[TEST_INFO]"
#define MAX_SMALL_BUFFER_SIZE 256

  /*!
    A function similar to C lib snprintf that return a string for convenient use.
   */
  template< typename... Args >
  std::string string_snprintf(unsigned int length, const char* pFormat, Args... args)
  {
    assert(length <= MAX_SMALL_BUFFER_SIZE);
    std::snprintf(gSmallBuffer, length, pFormat, args...);
    return std::string(gSmallBuffer);
  }

}

#endif
